# -*- coding: utf-8-*-
from openerp.osv import osv
from openerp.osv import fields
from openerp.addons.dftg_weixin.application.application_weixin_contact import WxAppContact
from weixin_sync_operation import WXSyncOperation
import copy
import json
import logging

_logger = logging.getLogger(__name__)


class res_partner(osv.osv):
    _inherit = 'res.partner'

    def _diff_contacts(self, cr, uid, partner, contacts):
        diff_list = ['name', 'mobile', 'email', 'department']
        for diff_field in diff_list:
            if diff_field == 'department':
                department = self.pool.get('res.partner')._get_department_by_partner(cr, uid, partner)
                if json.dumps(department) != contacts.department:
                    return True

            elif getattr(partner, diff_field) != getattr(contacts, diff_field):
                return True

        return False

    def _get_is_weixin_contacts_changed(self, cr, uid, ids, field_name, arg, context=None):
        res = {}
        for partner in self.browse(cr, uid, ids, context=context):
            res.update({partner.id: False})
        return res

    def _get_contacts_by_weixin_contacts(self, cr, uid, ids, context=None):
        return [contacts.partner_id.id for contacts in self.browse(cr, uid, ids, context=context) if not contacts.contacts_id]

    _columns = {
        'is_weixin_contacts_changed': fields.function(_get_is_weixin_contacts_changed, type='boolean', string=u'微信联系人是否修改',
            store={
                'res.partner': (lambda self, cr, uid, ids, ctx=None: ids, ['child_contacts_ids', 'name', 'mobile', 'email', 'supplier', 'customer', 'contacts'], 10),
                'weixin.contacts': (_get_contacts_by_weixin_contacts, ['is_disabled'], 10),
            }),
        'contacts_ids': fields.one2many('weixin.contacts', 'partner_id', u'微信联系人'),
    }


class company_contacts(osv.osv):
    _inherit = 'company.contacts'

    def _diff_contacts(self, cr, uid, contacts, weixin_contacts):
        diff_list = ['name', 'position', 'mobile', 'email', 'department']
        for diff_field in diff_list:
            if diff_field == 'department':
                department = self.pool.get('res.partner')._get_department_by_partner(cr, uid, contacts.partner_id)
                if json.dumps(department) != contacts.department:
                    return True

            elif diff_field == 'position':
                if contacts.position != weixin_contacts.position:
                    return True

            elif getattr(contacts.contacts_id, diff_field) != getattr(weixin_contacts, diff_field):
                return True

        return False

    def _get_is_weixin_contacts_changed(self, cr, uid, ids, field_name, arg, context=None):
        res = {}
        for contacts in self.browse(cr, uid, ids, context=context):
            if contacts.contacts_id and contacts.contacts_id.mobile:
                res.update({contacts.id: True})
                for weixin_contacts in contacts.contacts_ids:
                    if self._diff_contacts(cr, uid, contacts, weixin_contacts):
                        res.update({contacts.id: True})
                        break
                    else:
                        res.update({contacts.id: False})

            else:
                res.update({contacts.id: False})
                continue

        return res

    def _get_contacts_by_partner(self, cr, uid, ids, context=None):
        return self.pool.get('company.contacts').search(cr, uid, [('contacts_id', 'in', ids), ('is_inauguratory', '=', True)], context=context)

    def _get_contacts_by_weixin_contacts(self, cr, uid, ids, context=None):
        return [weixin_contacts.contacts_id.id for weixin_contacts in self.browse(cr, uid, ids, context=context) if weixin_contacts.contacts_id]

    _columns = {
        'is_weixin_contacts_changed': fields.function(_get_is_weixin_contacts_changed, type='boolean', string=u'微信联系人是否修改',
            store={
                'company.contacts': (lambda self, cr, uid, ids, ctx=None: ids, ['contact_id', 'position', 'mobile'], 10),
                'res.partner': (_get_contacts_by_partner, ['name', 'mobile', 'email', 'customer', 'supplier'], 10),
                'weixin.contacts': (_get_contacts_by_weixin_contacts, ['is_disabled'], 10),
            }),
        'contacts_ids': fields.one2many('weixin.contacts', 'contacts_id', u'微信联系人'),
    }


class weixin_contacts(osv.osv):
    _name = 'weixin.contacts'

    # 用来自动完成res.partner或company.contacts修改后同步到weixin.contacts的动作
    def diff_contacts(self, cr, uid, context=None):
        partner_obj = self.pool.get('res.partner')
        contacts_obj = self.pool.get('company.contacts')

        contacts_ids = contacts_obj.search(cr, uid, [('is_weixin_contacts_changed', '=', True)], context=context)
        partner_contacts_ids = [contacts.partner_id.id for contacts in contacts_obj.browse(
            cr, uid, contacts_ids, context=context) if contacts.partner_id]
        partner_ids = partner_obj.search(cr, uid, [('is_weixin_contacts_changed', '=', True)], context=context)

        partner_ids = list(set(partner_ids + partner_contacts_ids))

        partner_vals = partner_obj.gather_vals(cr, uid, partner_ids, context=context)
        partner_obj.check_vals(cr, uid, partner_vals, context=context)
        partner_obj.sync_values(cr, uid, partner_vals, context=context)

        cr.execute(
            '''
            UPDATE weixin_contacts SET sync_status='delete'
            WHERE partner_id IS NULL OR (origin = 'contacts' AND contacts_id IS NULL)
            '''
        )

        cr.commit()

    def _get_contacts_by_create(self, cr, uid, contacts):
        return {
            'userid': contacts.id,
            'name': contacts.name,
            'position': contacts.position,
            # 'department': self.pool.get('res.partner')._get_department_by_partner(cr, uid, contacts.partner_id),
            'department': [department.department_id for department in contacts.department],
            'mobile': contacts.mobile,
            'email': contacts.email,
        }

    def _get_contacts_by_update(self, cr, uid, contacts):
        res = {}
        if contacts.update_list:
            update_list = json.loads(contacts.update_list)
            res = {'userid': contacts.id}
            for field_name in update_list:
                if field_name == 'department':
                    res.update({field_name: [department.department_id for department in contacts.department]})
                elif field_name in ['isleader']:
                    res.update({field_name: '1' if getattr(contacts, field_name) else '0'})
                else:
                    res.update({field_name: getattr(contacts, field_name)})
        return res

    def sync_contacts(self, cr, uid, ids=None, context=None):
        cron_contacts_ids = ids or self.search(cr, uid, ['|', ('sync_status', '!=', False),
            ('sync_status', '!=', '')], order='sync_status desc', context=context)

        return self._sync_contacts(cr, uid, cron_contacts_ids, context=context)

    # 被设计用来作为同步任务的时候调用的函数
    def cron_sync_contacts(self, cr, uid, context=None):
        # 在同步的时候需要再次检查一下是否存在需要同步的数据
        self.diff_contacts(cr, uid, context=context)
        return self.sync_contacts(cr, uid, context=context)

    def _sync_contacts(self, cr, uid, ids, context=None):
        weixin_contact = WxAppContact()
        access_token = weixin_contact.access_token
        batch_vals = []
        for contacts in self.browse(cr, uid, ids, context=context):
            if contacts.sync_status == 'delete':
                self.write(cr, uid, contacts.id, {'active': False}, context=context)
                batch_vals = {"userid": contacts.id, 'enable': 0}
                WXSyncOperation.sync_user_by_operation(access_token, batch_vals, operation='update')
            elif contacts.sync_status == 'create':
                try:
                    WXSyncOperation.sync_user_by_operation(access_token, self._get_contacts_by_create(cr, uid, contacts), operation='create')
                except osv.except_osv, e:
                    raise osv.except_osv(u'错误', '%s' % e.value)
                    break
            elif contacts.sync_status == 'update':
                WXSyncOperation.sync_user_by_operation(access_token, self._get_contacts_by_update(cr, uid, contacts), operation='update')
            contacts.write({'sync_status': '', 'update_list': ''})

    def _get_is_disabled(self, cr, uid, ids, field_name, arg, context=None):
        res = {}
        for contacts in self.browse(cr, uid, ids, context=context):
            if contacts.odoo_user_id and not contacts.odoo_user_id.active:
                res.update({contacts.id: True})
            else:
                res.update({contacts.id: False})
        return res

    def write(self, cr, uid, ids, vals, context=None):
        for contacts in self.browse(cr, uid, ids, context=context):
            update_vals = copy.deepcopy(vals)
            for field in ['odoo_user_id', 'partner_id', 'is_follow', 'is_disable',
                          'sync_status', 'weixinid', 'contacts_id']:
                if field in update_vals.keys():
                    del update_vals[field]
            update_list = update_vals.keys()
            if vals.get('sync_status', 'default_vals') == 'default_vals':
                if contacts.update_list and contacts.sync_status == 'update' and contacts.update_list != 'null':
                    update_list.extend(eval(contacts.update_list))
                    vals.update({'update_list': json.dumps(list(set(update_list)))})
                else:
                    vals.update({'update_list': json.dumps(update_list)})
            if contacts.sync_status != 'create' and vals.get('update_list'):
                vals.update({'sync_status': 'update'})
        return super(weixin_contacts, self).write(cr, uid, ids, vals, context=context)
        
    def _get_contacts_by_users(self, cr, uid, ids, context=None):
        return self.pool.get('weixin.contacts').search(cr, uid, [('odoo_user_id', 'in', ids)], context=context)

    _columns = {
        'partner_id': fields.many2one('res.partner', u'业务伙伴', index=True),
        'contacts_id': fields.many2one('company.contacts', u'联系人', index=True),
        'name': fields.char(u'姓名'),
        'weixinid': fields.char(u'微信号'),
        'mobile': fields.char(u'手机号码', index=True),
        'email': fields.char(u'邮箱'),
        'position': fields.char(u'职位'),
        'isleader': fields.boolean(u'是领导'),
        'telephone': fields.char(u'电话号'),
        'odoo_user_id': fields.many2one('res.users', u'odoo用户'),
        'sync_status': fields.selection([('create', u'待新建'), ('delete', u'待删除'), ('update', u'待更新')], u'同步状态'),
        # 来源字段，记录这条记录是由res.partner还是company.contacts生成的
        'origin': fields.selection([('partner', 'Partner'), ('contacts', 'Contacts')], u'来源'),
        'is_follow': fields.boolean(u'是否关注', help=u'根据用户二次验证的消息和用户不关注的消息来更新这个字段值'),
        'is_disabled': fields.function(_get_is_disabled, type='boolean', string=u'是否禁用', help=u'根据user_id对应的用户表记录是否禁用来设置',
            store={
                'weixin.contacts': (lambda self, cr, uid, ids, ctx=None: ids, ['odoo_user_id'], 10),
                'res.users': (_get_contacts_by_users, ['active'], 10),
            }),
        'active': fields.boolean(u'有效', help=u'如果微信端被删除，则actived置为False，默认值为True（作用是保留微信端被删除的副本）'),
        'update_list': fields.char(u'待更新列表'),  # 用来记录需要更新的字段列表
        'department': fields.many2many('wechat.department', 'contact_department_rel', 'contact_id', 'department_id',
                                       string='部门ID')
    }

    _defaults = {
        'active': True,
        'sync_status': 'create',
    }

    _sql_constraints = [
        ('uniq_mobile', 'UNIQUE(mobile)', u'微信通讯录手机号码必须唯一')
    ]
